package com.jielihaofeng.shop.security.security;

import cn.hutool.core.util.StrUtil;
import com.jielihaofeng.shop.security.config.bean.SecurityProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.GenericFilterBean;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

/**
 * @author Johnnie Wind
 * @description token过滤器
 * @date 2021/2/26 17:02
 */
public class TokenFilter extends GenericFilterBean {

    private static final Logger log = LoggerFactory.getLogger(TokenFilter.class);

    private final TokenProvider tokenProvider;
    private final SecurityProperties properties;

    public TokenFilter(TokenProvider tokenProvider, SecurityProperties properties) {
        this.tokenProvider = tokenProvider;
        this.properties = properties;
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest)servletRequest;
        String token = resolveToken(httpServletRequest);
        if (StrUtil.isNotBlank(token)){
            Authentication authentication = tokenProvider.getAuthentication(token);
            SecurityContextHolder.getContext().setAuthentication(authentication);
            // token续期
            tokenProvider.checkRenewal(token);
        }
        filterChain.doFilter(servletRequest,servletResponse);
    }

    /**
     * @description 获取请求中的token，去除前缀
     * @author Johnnie Wind
     * @date 2021/2/27 9:01
     * @Param [request]
     * @return java.lang.String
     */
    private String resolveToken(HttpServletRequest request){
        String bearerToken = request.getHeader(properties.getHeader());
        if (StringUtils.hasText(bearerToken) && bearerToken.startsWith(properties.getTokenStartWith())){
            // 去掉令牌前缀
            return bearerToken.replace(properties.getTokenStartWith(),"");
        }else{
            log.error("非法token:{}",bearerToken);
        }
        return null;
    }
}
